VKPlayer = (function($, self, undefined) {

    self.Models = {

        /* Models.Artist */
        Artist: Backbone.Model.extend({
            initialize: function() {

            },
            defaults: {
                'artist':       'Unknown artist',
                'title':        ''
            }
        }),

        /* Models.Track */
        Track: Backbone.Model.extend({
            initialize: function() {
                if (USER.get('uid') == this.get('owner_id'))
                    this.set({isMyTrack: true});

                var hash = md5(this.get('artist') + ' ' + this.get('title'));
                this.set({hash: hash});

				var search_query = this.get('artist') + ' ' + this.get('title');
                this.set({video_query: search_query});
                this.set({download_query: search_query});

            },
            defaults: {
                'artist':       'Unknown artist',
                'title':        '',
                'attitude':     '',
				'links': []  //* Collections.Links */
            }

        }),

        /* Models.Album */
        Album: Backbone.Model.extend({
            initialize: function() {
            },
            defaults: {
                title:            'Unknown album',
                tracklist:        [] //* Collections.Tracks */
            }
        }),

        /* Models.User */
        User: Backbone.Model.extend({
            initialize: function() {
            },
            defaults: {
                'friends':        [], //* Collections.Users */
                'tracklist':    [], //* Models.Tracklist */
                'albums':        [] //* Collections.Albums */
            },

            events: {
                'loadTracklist':    'loadTracklist'
            },

            loadFriends: function() {
                var model = this;
                var uid = model.get('uid');
                var friends = model.get('friends');
                if (_.isEmpty(friends)) {
                    getFriends(uid)
                        .done(function(result) {
                            if (result) {
                                friends = new self.Collections.Users(result);
                                model.set({friends: friends});
                                model.trigger('friends_loaded');
                            }
                        });
                } else {
                    model.trigger('friends_loaded');
                }
            },

            loadTracklist: function() {
                var model = this;
                var uid = model.get('uid');
                var tracklist = this.get('friends');
                if (_.isEmpty(tracklist)) {
                    getAudio(uid)
                        .done(function(result) {
                            if (_.isArray(result)) {
                                var tracks = new self.Collections.Tracks(result);
                                tracklist = new self.Models.Tracklist();
                                tracklist.linkTracks(tracks);
                                tracklist.set({owner: model});
                                model.set({tracklist: tracklist});
                                model.trigger('tracklist_loaded');
                            }
                        });
                } else {
                    model.trigger('tracklist_loaded');
                }
            }
        }),

        /* Models.Tracklist */
        Tracklist: Backbone.Model.extend({
            initialize: function() {
                this.view = new self.Views.models.Tracklist({model: this});
            },
            defaults: {
                title:         '',
                tracks:        [] //* Collections.Tracks */
            },
            linkTracks: function(tracks) {
                var model = this;
                tracks.each(function(track) {
                    track.set({tracklist: model});
                });
                this.set({tracks: tracks});
            }
        }),

        /* Models.Player */
        Player: Backbone.Model.extend({
            initialize: function() {
                this.view = new self.Views.models.Player({model: this});
                this.bind('loopChange', this.loopChange, this);
                this.bind('shuffleChange', this.shuffleChange, this);
            },
            defaults: {
                'tracklist':    [],
                'muted':        '',
                'loop':         '',
                'shuffle':      ''
            },
            isMuted: function() {
                return this.get('muted');
            },
            loopChange: function(data) {
                if (data) {
                    this.set({loop    : data.loop });
                    this.set({loopClass    : data.loop ? 'repeat' : ''});
                }
            },
            isLoop: function() {
                return this.get('loop');
            },
            shuffleChange: function(data) {
                if (data) {
                    this.set({shuffle: data.shuffle });
                    this.set({shuffleClass: data.shuffle ? 'shuffle' : ''});
                }
            },
            isShuffle: function() {
                return this.get('shuffle');
            }

        }),

		/* Models.VideoPlayer */
        VideoPlayer: Backbone.Model.extend({
            defaults: {
                'video_list':    [],
				'type': 'Vk'
            }

        }),

        /* Models.Deque */
        Deque: Backbone.Model.extend({
            initialize: function() {
                this._queue = {
                    tracklists: new self.Collections.Tracklists,
                    tracks: new self.Collections.Tracks,
                    users: new self.Collections.Users,
                    /* очередь людей для синка треклистов */
                    owners: new self.Collections.Users
                };
                setInterval(_.bind(this.processTracklists, this), 7000);
                setInterval(_.bind(this.processTracks, this), 1200);
                setInterval(_.bind(this.processUsers, this), 10000);
                setInterval(_.bind(this.processOwners, this), 5000);
            },
            pushFront: function(model, type) {
                if (!_.isEmpty(model) && this._queue.hasOwnProperty(type)) {
                    this._queue[type].add(_.clone(model), {at:0});
                }
            },
            pushBack: function(model, type) {
                if (!_.isEmpty(model) && this._queue.hasOwnProperty(type)) {
                    this._queue[type].add(_.clone(model));
                }
            },
            popFront: function(type) {
                var model;
                if (this._queue.hasOwnProperty(type)) {
                    var _model = this._queue[type].first();
                    model = _.clone(_model);
                    this._queue[type].remove(_model);
                }
                return model;
            },
            popBack: function(type) {
                var model;
                if (this._queue.hasOwnProperty(type)) {
                    var _model = this._queue[type].last();
                    model = _.clone(_model);
                    this._queue[type].remove(_model)
                }
                return model;
            },
            rotateUserFriends: function(uid) {
                var thisDeque = this;
                getFriends(uid)
                    .done(function(result) {
                        if (result) {
                            var friends = new self.Collections.Users(result);
                            friends.each(function(owner) {
                                thisDeque.pushBack(owner, 'owners');
                            });
                        }
                    });
            },
            processTracklists: function() {
                if (DOWNLOADING || this._queue.tracklists.isEmpty())
                    return;

                var tlModel = this.popFront('tracklists');
                var owner = tlModel.get('owner');
                var tracks = tlModel.get('tracks');

                var playlistSync = _.after(1, function() {

                });

                if (_.isEmpty(owner)) {
                    return;
                } else {
                }

                var uid = owner.get('uid');
                var hashes = tracks.pluck('hash');

                $.ajax({
                    url: '/playlist_sync',
                    type: 'POST',
                    data: {owner: uid, hashes: hashes},
                    dataType: 'json'
                })
                    .success(function(data) {
                        if (data.success) {
                            if (! _.isEmpty(data.unknown_hashes)) {
                                var unknown_hashes = (data.unknown_hashes == 'all') ? hashes : data.unknown_hashes;
                                _.each(unknown_hashes, function(hash) {
                                    var track = _.first(tracks.getByHash(hash));
                                    DEQUE.pushBack(track, 'tracks');
                                });
                            }

                            if (data.unknown_user) {
                                DEQUE.pushBack(owner, 'users');
                            }
                        }
                    })
                    .error(function(data) {
                    });
            },
            processTracks: function() {
                if (DOWNLOADING || this._queue.tracks.isEmpty())
                    return;

                var trackModel = this.popFront('tracks');
                setTrackLink(trackModel);
            },
            processUsers: function() {
                if (DOWNLOADING || this._queue.users.isEmpty())
                    return;

                var userModel = this.popFront('users');
                var uid = userModel.get('uid');
                getProfiles(uid)
                    .done(function(result) {
                        if (result) {
                            $.ajax({
                                url: '/validate_user',
                                type: 'POST',
                                data: {profiles: result},
                                dataType: 'json'
                            })
                                .success(function(data) {
                                })
                                .error(function(data) {
                                });
                        }
                    })
            },
            processOwners: function() {
                if (DOWNLOADING || this._queue.owners.isEmpty())
                    return;

                var userModel = this.popFront('owners');
                var uid = userModel.get('uid');
                self.loadTracklist(uid);
            }
        }),

		/* Models.Link */
        Link: Backbone.Model.extend({
            initialize: function() {
            },
            defaults: {
                'title': '',
				'href': []  //* Collections.Links */
            }
        }),

		 /* Models.Track */
        VideoVk: Backbone.Model.extend({
            initialize: function() {

            }

        })

    };
	return self;
	
})(jQuery, VKPlayer || {});
